#ifndef CRECIPEMODEL_H
#define CRECIPEMODEL_H

#include <QObject>
#include <QSqlTableModel>
#include "cconstdefinition.h"
#include "cmodel.h"
#include "crecipefilter.h"

namespace cooking {

class CRecipeModel : public CModel
{
    Q_OBJECT
    Q_PROPERTY(int cuisineId READ cuisineId WRITE setCuisineId NOTIFY cuisineIdChanged)
    Q_PROPERTY(CRecipeFilter* filter READ filter WRITE setFilter NOTIFY filterChanged)

public:
    explicit CRecipeModel(CEngine& engine, QObject *parent = 0);
    CRecipeModel(int cuisineId, CEngine& engine, QObject *parent = 0);
    ~CRecipeModel();
    int rowCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    int cuisineId();
    void setCuisineId(int cuisineId);

    CRecipeFilter* filter();
    /**
     * Set recipe filter
     * @param filter Recipe filter, ownership is not transferred
     */
    void setFilter(CRecipeFilter* filter);

signals:
    void cuisineIdChanged();
    void filterChanged();

public slots:


protected:
    QString queryString();
    void initRoles();
    void refresh();

private:
    void sqlAddListNumber(QString& sql, QList<int>& list);
    void sqlAddIntersect(QString& sql, bool& added, const QString intersectSql);
    void sqlAddWhereUnion(QString& sql, const QString& subSql);

    //Ingredient
    QString sqlIngredients();
    QString sqlIngredientsExist();
    QString sqlIngredientsInclude();
    QString sqlIngredientsExclude();
    QString sqlIngredientsMay();

    //Recipe
    QString sqlRecipe();
    void sqlAddAnd(QString& sql, bool filterAdded);
    void sqlAddRecipeColumnFilter(QString& sql,
                                  bool& filterAdded,
                                  QString column,
                                  QList<int>& inList,
                                  QList<int>& exList,
                                  QList<int>& mayList);

    //cuisine
    QString sqlCuisine();
    QString sqlCuisineInclude();
    QString sqlCuisineExclude();
    QString sqlCuisineMay();

    //readytime
    QString sqlReadyTime();
    int sqlFindLeast(QList<int>& list);
    int sqlFindLargest(QList<int>& list);

    //nutrition
    QString sqlNutritions();
    QString sqlNutritionFilterReverseString(
        CNutritionFilter& filter, const QString& nutritonIdStr,
        const QString& nutritionSumStr);
    QString sqlNutritionFilterString(
        CNutritionFilter& filter, const QString& nutritonIdStr,
        const QString& nutritionSumStr);
    void sqlNutritionReverseFilter(
        CNutritionFilter& filter,
        CNutritionFilter& reverse);
    bool sqlNutritionsHasPerServe();

private:
    int m_cuisineId;
    const static QString KRecipeRoleNamesMap[][2];
    int m_roleStart;
    int m_roleEnd;
    CRecipeFilter m_filter;
};
} // namespace cooking
#endif // CRECIPEMODEL_H
